const DB_NAME = "annotator-editor";
const DB_VERSION = 1;
let db: IDBDatabase | null = null;

// 定义存储区配置类型
interface StoreConfig {
  name: string;
  params: MyPartial<{
    keyPath: string;
    autoIncrement: boolean;
  }>;
  indexes?: { name: string; keyPath: string }[];
}

const storeConfigs: StoreConfig[] = [
  {
    name: "articles",
    params: {
      keyPath: "id",
    },
    indexes: [
      { name: "is_deleted", keyPath: "is_deleted" },
      { name: "delete_time", keyPath: "delete_time" },
    ],
  },
  {
    name: "history",
    params: {
      keyPath: "id",
      autoIncrement: true,
    },
    indexes: [
      { name: "articleId", keyPath: "articleId" },
      { name: "timestamp", keyPath: "timestamp" },
    ],
  },
];

// 打开数据库
const openDB = (): Promise<IDBDatabase> => {
  return new Promise((resolve, reject) => {
    const request = indexedDB.open(DB_NAME, DB_VERSION);

    request.onupgradeneeded = (event) => {
      const db = (event.target as IDBOpenDBRequest).result;

      // 遍历配置创建存储区
      storeConfigs.forEach((config) => {
        if (!db.objectStoreNames.contains(config.name)) {
          console.log(`创建存储区: ${config.name}`);
          const store = db.createObjectStore(config.name, config.params);
          config.indexes?.forEach((index) => {
            store.createIndex(index.name, index.keyPath);
          });
        }
      });

      upgradeDB(db);
    };

    request.onsuccess = (event) => {
      db = (event.target as IDBOpenDBRequest).result;
      migrateData(db);
      resolve(db);
    };

    request.onerror = (event) => {
      reject((event.target as IDBOpenDBRequest).error);
    };
  });
};

// 修改数据库版本和升级逻辑
const upgradeDB = (db: IDBDatabase) => {
  if (!db.objectStoreNames.contains("articles")) {
    const store = db.createObjectStore("articles", { keyPath: "id" });
    // 创建需要的索引
    store.createIndex("is_deleted", "is_deleted", { unique: false });
    store.createIndex("delete_time", "delete_time", { unique: false });
  }
};

// 新增字段后的数据迁移
const migrateData = async (db: IDBDatabase) => {
  const tx = db.transaction("articles", "readwrite");
  const store = tx.objectStore("articles");
  const req = store.getAll();

  req.onsuccess = () => {
    req.result.forEach((article) => {
      if (article.is_deleted === undefined) {
        article.is_deleted = 0;
        store.put(article);
      }
    });
  };
};

// 保存更新数据
const updateData = async (
  storeName: string,
  data: any,
  method: "put" | "add" = "add"
) => {
  if (!db) {
    db = await openDB();
  }
  return new Promise((resolve, reject) => {
    const transaction = db!.transaction(storeName, "readwrite");
    const store = transaction.objectStore(storeName);
    const request = store[method](data);

    request.onsuccess = () => {
      resolve(request.result);
    };

    request.onerror = () => {
      console.error("操作失败:", request.error);
      reject(request.error);
    };
  });
};

// 获取数据
const getData = async (storeName: string, key?: string) => {
  if (!db) {
    db = await openDB();
  }
  return new Promise((resolve, reject) => {
    const transaction = db!.transaction(storeName, "readonly");
    const store = transaction.objectStore(storeName);
    const request = key ? store.get(key) : store.getAll();

    request.onsuccess = () => {
      resolve(request.result);
    };

    request.onerror = () => {
      reject(request.error);
    };
  });
};

// 删除数据
const deleteData = async (
  storeName: string,
  id?: string | number // id 参数变为可选
) => {
  if (!db) {
    db = await openDB();
  }

  return new Promise((resolve, reject) => {
    const transaction = db!.transaction(storeName, "readwrite");
    const store = transaction.objectStore(storeName);
    const request = id !== undefined ? store.delete(id) : store.clear();
    console.log(`${storeName} 删除成功`, id);
    request.onsuccess = () => {
      resolve(request.result);
    };

    request.onerror = () => {
      reject(request.error);
    };
  });
};

// 根据 键名与 键值 删除其所有数据（比如根据 articleId 删除其所有历史记录）
const deleteAllDataByKey = async (
  storeName: string,
  keyName: string,
  keyValue: string
) => {
  if (!db) {
    db = await openDB();
  }
  return new Promise((resolve, reject) => {
    const transaction = db!.transaction(storeName, "readwrite");
    const store = transaction.objectStore(storeName);
    const index = store.index(keyName); // 使用指定键名创建索引
    const request = index.openCursor(IDBKeyRange.only(keyValue)); // 根据键值过滤

    request.onsuccess = (event) => {
      const cursor = (event.target as IDBRequest<IDBCursorWithValue>).result;
      if (cursor) {
        cursor.delete(); // 删除匹配的记录
        cursor.continue();
      } else {
        resolve(null); // 所有匹配项已删除
      }
    };

    request.onerror = () => {
      reject(request.error);
    };
  });
};

// 根据字段名与字段值获取数据
const getDataByIndex = async (
  storeName: string,
  keyName: string,
  keyValue: any
): Promise<any[]> => {
  if (!db) {
    db = await openDB();
  }
  return new Promise((resolve, reject) => {
    const transaction = db!.transaction(storeName, "readonly");
    const store = transaction.objectStore(storeName);
    const index = store.index(keyName);
    const request = index.openCursor(IDBKeyRange.only(keyValue));
    const results: any[] = [];

    request.onsuccess = (event) => {
      const cursor = (event.target as IDBRequest<IDBCursorWithValue>).result;
      if (cursor) {
        results.push(cursor.value);
        cursor.continue();
      } else {
        resolve(results);
      }
    };

    request.onerror = () => {
      reject(request.error);
    };
  });
};

// 导出所有功能
export default {
  openDB,
  updateData,
  getData,
  deleteData,
  deleteAllDataByKey,
  getDataByIndex,
};
